#include <iostream>
#include <vector>
using namespace std;

typedef vector< unsigned int>   vuint;
typedef vector< bool>   vbool; 
typedef vector< vector<bool> > vvbool;
typedef pair<unsigned int,unsigned int> par;


// Función que devuelve si una posición está en el rango del tablero adecuado.
bool posValida(unsigned int i, unsigned int N){
    return (i < N);
}

// Función que devuelve si no es posible ubicar K alfiles en un tablero de N casillas
bool juegoImposible(unsigned int K, unsigned int N){
    return( K > (2 * N) - 2);
}

// Idem juegoImposible pero para una división particular de alfiles.
bool divImposible(unsigned int K, unsigned int N){
    return( K > N - 1);
}

// Verifica si la diagonal derecha esta libre para una posición dada.    
bool diagDerLibre(par pos, unsigned int N, vvbool &diags){
    
	if (pos.second >= pos.first){
	    return diags[0][pos.second - pos.first];
	} else{
	    return diags[1][pos.first - pos.second];
	}
} 

// Verifica si la diagonal izquierda esta libre para una posición dada.
bool diagIzqLibre(par pos, unsigned int N, vvbool &diags){
   
    unsigned int suma = pos.first + pos.second;
    if (suma >= N) {
		return  diags[2][suma - (N - 1)];
    } else { 
    	return diags[3][suma];
	}
}

// Verifica si las diagonales que intersecan una posicion estan libres.
bool diagonalesLibres(par pos, unsigned int N, vvbool &diags){
    return diagDerLibre(pos, N, diags) && diagIzqLibre(pos, N, diags);
}        

// Setea la diagonal derecha de una posicion como ocupada o libre dependiendo del valor de seteo.
void setearDer(par pos, unsigned int N, vvbool &diags,bool seteo){
    
	if (pos.second >= pos.first){
	    diags[0][pos.second - pos.first] = seteo;
	} else {
	    diags[1][pos.first - pos.second] = seteo;
	}  
} 

// Setea la diagonal izquierda de una posicion como ocupada o libre dependiendo del valor de seteo.
void setearIzq(par pos, unsigned int N, vvbool &diags,bool seteo){
   
    unsigned int suma = pos.first + pos.second;
    if (suma >= N) {
		diags[2][suma - (N - 1)] = seteo;
    } else { 
    	diags[3][suma] = seteo;
	}
}

// Setea las diagonales de una posicion como ocupada o libre dependiendo del valor de seteo.
void setearDiagonales(par pos, unsigned int N, vvbool &diags, bool seteo){  
    setearDer(pos, N, diags, seteo);
    setearIzq(pos, N, diags, seteo);
}

// Pasa a la siguiente posición de un tablero, el mismo se recorre fila por fila.
par siguiente(par pos,unsigned int  N){
    par res;
    if (!posValida(((pos.second) + 2) , N)){
	    res.first = pos.first + 1;
	    if (N % 2 == 0){
			(pos.second == N - 1) ?	res.second = 0 :res.second = 1;
		} else{
			(pos.second == N - 1) ? res.second = 1 : res.second = 0;
		}     
    } else {
		res.first = pos.first;
		res.second = pos.second + 2;
    }
    return res;
}

// Función que realiza el backtracking   
int littleBitshops(par pos, unsigned int N, unsigned int K,vvbool &diags, unsigned int puestos){
		
	if (K == 0) return 1;
	
	if (!posValida(pos.first, N)) return 0;

	int res = 0;

	if (diagonalesLibres(pos, N, diags)){
	    
	    setearDiagonales(pos, N, diags, 0);
	    if  (puestos + 1 == K){
			res += 1;
	    } else {
			res += littleBitshops(siguiente(pos, N), N, K, diags, puestos + 1);
		}
	
	    setearDiagonales(pos, N, diags, 1); 
	}	
	    
	res += littleBitshops(siguiente(pos, N), N, K, diags, puestos);    
	    
	return res;
	
}

// Función principal que se encarga de filtrar casos bordes y divide el tablero en negras y blancas.
int main(){
    
    unsigned int N, K =0;
    unsigned int res;
    par posN (0,0);
    par posB (0,1);

    cin >> N >> K;
		   
    while (!(N <= 0 && K <= 0)){
		res = 0;
		if(N > 0 && N <= 8){    
			if (N == 1){
				(K <= 1) ? res = 1 : res = 0;
			} else{
				if(!juegoImposible(K,N)){
					if (N % 2 == 0){
						vuint resultados(K + 1, 0);
						for (unsigned int grupo = 0; grupo <= min(K,N-1); grupo++ ){
							if(!divImposible(grupo ,N)){
								vvbool diags(4, vbool(N, 1));
								resultados[grupo] = littleBitshops(posN, N, grupo, diags, 0);
							}
						}   
						for (unsigned int grupo = 0; grupo < (K/2); grupo++ ){
							res += 2 * (resultados[grupo] * resultados[K - grupo]);
						}
						(K % 2 == 0) ? res += resultados[K/2] * resultados[K/2]:
							res += 2 * (resultados[K/2] * resultados[K - (K/2)]);
					} else {
						for (unsigned int grupo = 0; grupo <= K; grupo++ ){
							if(!divImposible(grupo ,N) && !divImposible(K - grupo,N)) {
								vvbool diags(4, vbool(N, 1));
								res += littleBitshops(posN, N, grupo, diags, 0) * 
									littleBitshops(posB, N, (K - grupo), diags, 0);
							}
						}
					}	
				}	    
			}			  
        }
        cout << res << endl;
        cin >> N >> K; 
   }	
   return 0;
}
